package com.domor.system.service;

import com.domor.common.utils.AddressUtils;
import com.domor.common.utils.DateUtils;
import com.domor.common.utils.StringUtils;
import com.domor.common.utils.spring.SpringUtils;
import com.domor.system.domain.SysUser;
import com.domor.system.domain.SysUserOnline;
import com.domor.system.mapper.SysUserOnlineMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.server.session.DefaultWebSessionManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * <h3>在线用户 服务层</h3>
 * @author liyuyang
 * @date 2020/5/7
 **/
@Service
public class SysUserOnlineService {

    private static RedisSessionDAO sessionDAO = SpringUtils.getBean(RedisSessionDAO.class);

    /**
     * 通过会话序号查询信息
     *
     * @param sessionId 会话ID
     * @return 在线用户信息
     */
    public SysUserOnline selectOnlineById(String sessionId) {
        Session session = sessionDAO.readSession(sessionId);
        if (ObjectUtils.isNotEmpty(session)) {
            return ConvertSession(session);
        } else {
            return null;
        }
    }

    /**
     * session转换成SysUserOnline
     * @param session
     * @return
     */
    private SysUserOnline ConvertSession(Session session){
        SysUserOnline sysUserOnline = new SysUserOnline();
        sysUserOnline.setSessionId(session.getId().toString());
        sysUserOnline.setBrowser(session.getHost());
        sysUserOnline.setLastAccessTime(session.getLastAccessTime());
        sysUserOnline.setStartTimestamp(session.getStartTimestamp());
        sysUserOnline.setExpireTime(session.getTimeout());

        SimplePrincipalCollection s = (SimplePrincipalCollection)session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY");
        if (s != null) {
            SysUser sysUser = (SysUser)s.getPrimaryPrincipal();
            sysUserOnline.setLoginName(sysUser.getLoginName());
            sysUserOnline.setDeptName(sysUser.getDept().getDeptName());
            sysUserOnline.setIpaddr(sysUser.getLoginIp());
            String address = AddressUtils.getRealAddressByIP(sysUser.getLoginIp());
            sysUserOnline.setLoginLocation(address);
        }

        return  sysUserOnline;
    }

    /**
     * 通过会话序号删除信息
     *
     * @param sessionId 会话ID
     * @return 在线用户信息
     */
    public void deleteOnlineById(String sessionId) {
        Session session = sessionDAO.readSession(sessionId);
        if (ObjectUtils.isNotEmpty(session)) {
            sessionDAO.delete(session);
        }
    }

    /**
     * 通过会话序号删除信息
     *
     * @param sessions 会话ID集合
     * @return 在线用户信息
     */
    public void batchDeleteOnline(List<String> sessions) {
        for (String sessionId : sessions) {
            Session session = sessionDAO.readSession(sessionId);
            if (ObjectUtils.isNotEmpty(session)) {
                sessionDAO.delete(session);
            }
        }
    }

    /**
     * 查询会话集合
     *
     * @param userOnline 在线用户
     */
    public List<SysUserOnline> selectUserOnlineList(SysUserOnline userOnline) {
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        List<SysUserOnline> users = new ArrayList<>();
        for (Session s : sessions) {
            boolean b1 = true;
            boolean b2 = true;
            SysUserOnline user = ConvertSession(s);
            if (StringUtils.isNotEmpty(userOnline.getIpaddr())) {
                b1 = user.getIpaddr().contains(userOnline.getIpaddr());
            }
            if (StringUtils.isNotEmpty(userOnline.getLoginName())) {
                b2 = user.getLoginName().contains(userOnline.getLoginName());
            }
            if (b1 && b2) {
                users.add(user);
            }
        }
        return users;
    }

    /**
     * 强退用户
     *
     * @param sessionId 会话ID
     */
    public void forceLogout(String sessionId) {
        Session session = sessionDAO.readSession(sessionId);
        if (ObjectUtils.isNotEmpty(session)) {
            sessionDAO.delete(session);
            // 设置会话的kickout属性表示踢出了
            session.setAttribute("kickout", true);
        }
    }

}
